package org.saxing.filter;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.saxing.entity.JSONResult;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.List;

/**
 * JWT生成，和验签的类
 *
 * Created by 17020639 on 2017/7/21.
 */
public class TokenAuthenticationService {

    static final long EXPIRATIONTIME = 432_000_000;// 5天
    static final String SECRET = "P@ssw02d";// JWT密码
    static final String TOKEN_PREFIX = "Bearer";// Token前缀
    static final String HEADER_STRING = "Authorization"; //存放Token的Header Key

    // JWT生成方法
    static void addAuthentication(HttpServletResponse response, String username){
        // 生成JWT
        String JWT = Jwts.builder()
                // 保存权限（角色）
                .claim("authorities", "ROLE_ADMIN,AUTH_WRITE")
                // 用户名写入标题
                .setSubject(username)
                // 有效期设置
                .setExpiration(new Date(System.currentTimeMillis()
                    + EXPIRATIONTIME))
                // 签名设置
                .signWith(SignatureAlgorithm.HS512, SECRET)

                .compact();

        // 将 JWT 写入 body
        try {
            response.setContentType("application/json");
            response.setStatus(HttpServletResponse.SC_OK);
            response.getOutputStream().println(JSONResult.fillResultString(0, "", JWT));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // JWT验证方法
    static Authentication getAuthentication(HttpServletRequest request){
        // 从Header中拿到token
        String token = request.getHeader(HEADER_STRING);

        if (token != null){
            Claims claims = Jwts.parser()
                    // 验签
                    .setSigningKey(SECRET)
                    // 去掉 Bearer
                    .parseClaimsJws(token.replace(TOKEN_PREFIX, ""))

                    .getBody();

            String user = claims.getSubject();

            List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList(
                    (String) claims.get("authorities"));

            return user != null
                    ? new UsernamePasswordAuthenticationToken(user, null, authorities)
                    : null;
        }
        return null;
    }

}
